package net.stevechaloner.idea.ffs.io;

import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiFile;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.project.Project;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

import org.jetbrains.annotations.NotNull;
import net.stevechaloner.idea.ffs.model.Translator;
import net.stevechaloner.idea.ffs.model.src.SrcModelTranslator;
import net.stevechaloner.idea.ffs.model.xml.XmlModelTranslator;
import net.stevechaloner.idea.ffs.FileType;

/**
 * @author Steve Chaloner
 */
public class GenericFileFactory<T extends PsiFile> implements FileFactory<T>
{
    /**
     *
     */
    private static final Map<FileType, Translator> TRANSLATORS = new HashMap<FileType, Translator>()
    {
        {
            put(FileType.XML,
                new XmlModelTranslator());
            put(FileType.SRC,
                new SrcModelTranslator());
        }
    };

    /**
     *
     * @param files all plugin files
     * @param type the type of file, denoted by extension
     * @return a list of {@link com.intellij.psi.xml.XmlFile}s based on the given files
     */
    public List<T> loadFiles(@NotNull Project project,
                             @NotNull VirtualFile[] files,
                             @NotNull FileType type) throws IOException
    {
        List<T> tFiles = new ArrayList<T>();
        PsiElementFactory psiElementFactory = PsiManager.getInstance(project).getElementFactory();

        StringBuilder stringBuilder = new StringBuilder();
        for (VirtualFile file : files)
        {
            if (type.getExtension().equalsIgnoreCase(file.getExtension()))
            {
                BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()));
                while (reader.ready())
                {
                    String line = reader.readLine();
                    if (type.getComment() == null || !line.startsWith(type.getComment()))
                    {
                        stringBuilder.append(line);
                    }
                }
                reader.close();
                String content = stringBuilder.toString();
                String name = file.getName();
                Translator translator = TRANSLATORS.get(type);
                PsiFile psiFile = psiElementFactory.createFileFromText((name.endsWith(type.getRequiredSuffix()) ? name : name + type.getRequiredSuffix()),
                                                                       translator.translateToIdeaFriendlyModel(content));
                tFiles.add((T)psiFile);
                stringBuilder.setLength(0);
            }
        }
        return tFiles;
    }
}
